/**
 * Universidad del Valle de Guatemala
 * Algoritmos y Estructura de Datos
 * Rodrigo Avelar; carné: 11192
 * programa basado de ejemplos en Java Structures de Duane A. Bailey
 */

public class BinaryTree {
    
    // Atributos del arbol binario
    protected Nodo val; 
    protected BinaryTree parent; 
    protected BinaryTree left, right; 

    /**
     * post: constructor que genera un nodo vacio
     */
    public BinaryTree(){
        val = null;
        parent = null; 
        left = right = this;
    }
    
    /**
     * post: genera un arbol que hace referencia a dos arboles vacios
     * @param value 
     */
    public BinaryTree(Nodo value){
        val = value;
        right = left = new BinaryTree();
        setLeft(left);
        setRight(right);
    }
   
    /**
     * post: retorna un arbol haciendo referencia a un valor y 2 subarboles
     * @param value
     * @param left
     * @param right 
     */
    public BinaryTree(Nodo value, BinaryTree left, BinaryTree right){
        val = value;
        if (left == null) { 
            left = new BinaryTree(); 
        }
        setLeft(left);
        if (right == null) { 
            right = new BinaryTree(); 
        }
        setRight(right);
    }
    
    /**
     * post: asigna un subarbol izquierdo
     * @param newLeft 
     */
    public void setLeft(BinaryTree newLeft){
        if (isEmpty()) return;
        if (left != null && left.parent() == this) left.setParent(null);
        left = newLeft;
        left.setParent(this);
    }
  
    /**
     * post: asigna un subarbol derecho
     * @param newRight 
     */
    public void setRight(BinaryTree newRight){
        if (isEmpty()) return;
        if (right != null && right.parent() == this) right.setParent(null);
        right = newRight;
        right.setParent(this);
    }
   
    /**
     * post: asigna un nuevo arbol
     * @param newParent 
     */
    protected void setParent(BinaryTree newParent){
        if (!isEmpty()) {
            parent = newParent;
        }
    }
    
    /**
     * post: retorna el arbol izquierdo
     * @return left
     */
    public BinaryTree left(){
        return left;
    }
    
    /**
     * post: retorna el arbol derecho
     * @return right
     */
    public BinaryTree right(){
        return right;
    }
    
    /**
     * post: retorna el arbol raiz
     * @return parent
     */
    public BinaryTree parent(){
        return parent;
    }
    
    /**
     * post: retorna el valor del nodo asociado al arbol
     * @return val
     */
    public Nodo value(){
        return val;
    }
    
    /**
     * post: asigna el valor del nodo asociado al arbol
     * @param value 
     */
    public void setValue(Nodo value){
        val = value;
    }
    
    /**
     * post: verifica si la raiz esta vacia
     * @return 
     */
    public boolean isEmpty(){
        if (parent != null){
            return false;
        }
        else{
            return true;
        }
    }
    
}
